package mongo

import (
	"errors"
	"fmt"
	"gopkg.in/mgo.v2"
	"log"
	"os"
	"strconv"
)

const (
	// MONGODB_URL = "mongodb://shiotoli:wO#a5P]2b@127.0.0.1:27018"
	MONGODB_URL = "mongodb://admin:123456@127.0.0.1:27017"
	MAX_COUNT   = 300
)

type MongoDB struct {
	Session  *mgo.Session
	Database string
}

var mdb *MongoDB

func New(database string) (*MongoDB, error) {
	session, err := mgo.Dial(MONGODB_URL)
	if err != nil {
		return nil, err
	}
	session.SetMode(mgo.Monotonic, true)
	return &MongoDB{
		Database: database,
		Session:  session}, nil
}
func Get(collection, symbol string, t int64) error {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	n, err := c.Find(map[string]interface{}{
		"symbol": symbol,
		"time":   t,
	}).Count()
	if err != nil {
		return err
	}
	if n > 0 {
		return errors.New("data already exist!")
	}
	return nil
}
func GetList(collection, symbol string, result interface{}) error {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	err := c.Find(map[string]interface{}{
		"symbol": symbol,
	}).Sort("-time").Skip(0).Limit(MAX_COUNT).All(result)
	if err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func Upsert(collection string, id int, data interface{}) error {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	_, err := c.UpsertId(id, data)
	if err != nil {
		return err
	}
	return nil
}
func CMSID2DBID(collection string, id int) string {
	return collection + "-" + strconv.Itoa(id)
}
func Insert(collection string, data interface{}) error {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	err := c.Insert(data)
	if err != nil {
		return err
	}
	return nil
}
func InsertMany(collection string, data []interface{}) error {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	err := c.Insert(data...)
	if err != nil {
		return err
	}
	return nil
}
func Update(collection string, id int, data interface{}) error {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	err := c.UpdateId(id, data)
	if err != nil {
		return err
	}
	return nil
}

func List(collection string, page, pageSize int) (interface{}, error) {
	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	var data []interface{}
	err := c.Find(map[string]interface{}{}).Skip((page - 1) * pageSize).Limit(pageSize).All(&data)
	if err != nil {
		return nil, err
	}
	return data, nil
}
func Delete(collection string, id int) error {

	s := mdb.Session.Copy()
	defer s.Close()
	c := s.DB(mdb.Database).C(collection)
	err := c.RemoveId(id)
	if err != nil && err != mgo.ErrNotFound {
		return err
	}
	return nil
}

func init() {
	var err error
	mdb, err = New("okex_data")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
